package cn.wanda.bi.sunshine.platform.server.aspect;

import cn.wanda.bi.sunshine.platform.server.controller.response.common.SimpleResponse;
import cn.wanda.bi.sunshine.platform.server.utils.JsonUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

/**
 * Created by wangfupeng1 on 2017-4-27.
 */
@Aspect
@Component
public class LogAspect {
    public Log log = LogFactory.getLog(LogAspect.class);

    @Autowired
    private HttpServletRequest request;

    @Around("within(cn.wanda.bi.sunshine.platform.server.aspect.Logging+)")
    public Object logger(ProceedingJoinPoint point) throws Throwable {
        long begin = System.currentTimeMillis();
        String methodDescription = "NONE";
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        for (Annotation annotation : method.getAnnotations()) {
            if (annotation instanceof ApiOperation) {
                methodDescription = ((ApiOperation) annotation).value();
            }
        }

        StringBuilder sb = new StringBuilder("\n==========【")
                .append(methodDescription).append(" ")
                .append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .append("】 ============================\n");

        sb.append("Controller  : ").append(point.getTarget().getClass().getSimpleName()).append("\n");
        sb.append("Method      : ").append(request.getMethod()).append("\n");

        String uri = request.getRequestURI();
        if (uri != null) sb.append("URL         : ").append(uri).append("\n");

        if (request.getHeader("Content-Type") != null
                && request.getHeader("Content-Type").equals(MediaType.APPLICATION_JSON_VALUE)
                && !request.getMethod().equals("GET")) {
            Object[] args = point.getArgs();
            if (args.length > 0) {
                for (Object arg : args) {
                    sb.append("PostArg     : ").append(arg).append("\n");
                }
            }
        }

        Enumeration<String> e = request.getParameterNames();
        if (e.hasMoreElements()) {
            sb.append("Parameter   : ");
            while (e.hasMoreElements()) {
                String name = e.nextElement();
                String[] values = request.getParameterValues(name);
                if (values.length == 1) {
                    sb.append(name).append("=").append(values[0]);
                } else {
                    sb.append(name).append("[]={");
                    for (int i = 0, length = values.length; i < length; i++) {
                        if (i > 0)
                            sb.append(",");
                        sb.append(values[i]);
                    }
                    sb.append("}");
                }
                sb.append(" ");
            }
            sb.append("\n");
        }

        SimpleResponse response = (SimpleResponse) point.proceed();

        if (response == null)
            sb.append("return      : ").append("null").append("\n");
        else
            sb.append("return      : ").append(JsonUtil.toJson(response)).append("\n");
        sb.append("tcost       : ").append(System.currentTimeMillis() - begin).append("ms").append("\n");
        sb.append("====================================================================\n");
        log.info(sb.toString());
        return response;
    }
}
